
package com.hyst.seviceImpl;

import java.text.ParseException;
import java.util.*;

import com.hyst.domain.*;
import com.hyst.repository.PurchaseCourseViewMapper;
import com.hyst.utils.GsonUtils;
import com.sun.org.apache.xpath.internal.operations.Bool;
import org.activiti.engine.impl.util.json.JSONObject;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.converter.json.GsonBuilderUtils;
import org.springframework.stereotype.Service;

import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.hyst.repository.CurriculumScheduleMapper;
import com.hyst.repository.PurchaseCourseMapper;
import com.hyst.service.CurriculumScheduleService;
import com.hyst.utils.DateUtil;
import com.hyst.utils.UuidTool;
import org.springframework.transaction.annotation.Transactional;

import cn.hutool.core.date.DateField;
import cn.hutool.core.date.DateTime;

/**
 * @Description:
 * @Date：2018年09月13日 @author： dy
 * @version ：1.0 1.[2018年09月13日]
 */
@Service
public class CurriculumScheduleServiceImpl implements CurriculumScheduleService {

	@Autowired
	private CurriculumScheduleMapper mapper;
	@Autowired
	private PurchaseCourseViewMapper purchaseCourseViewMapper;
	@Autowired
	PurchaseCourseMapper pcmapper;

	@Override
	public Page<CurriculumSchedule> list(final CurriculumSchedule curriculumSchedule) {
		final Page<CurriculumSchedule> page = PageHelper.startPage(curriculumSchedule.getPageNum(),
				curriculumSchedule.getPageSize());
		mapper.select(curriculumSchedule);
		return page;
	}

	@Override
	public CurriculumSchedule insert(final CurriculumSchedule curriculumSchedule) {
		mapper.insertSelective(curriculumSchedule);
		return curriculumSchedule;
	}

	@Override
	public CurriculumScheduleView getByPriKey(final Integer id) {
		CurriculumSchedule curriculumSchedule1= new CurriculumSchedule();
		curriculumSchedule1.setId(id);
		CurriculumScheduleView view = mapper.getView(curriculumSchedule1);
		String material = mapper.getMaterial(id);
		if(StringUtils.isNotBlank(material)){
			view.setMaterialLevel(Integer.valueOf(material));
		}
		return view;
	}

	@Transactional
	@Override
	public CurriculumSchedule updateSelective(final CurriculumSchedule curriculumSchedule) {
//		mapper.updateByPrimaryKeySelective(curriculumSchedule);
//		return curriculumSchedule;
		try {
			CurriculumSchedule curriculumScheduledb = mapper.selectByPrimaryKey(curriculumSchedule);
			PurchaseCourseView purchaseCourseView = purchaseCourseViewMapper.selectByPrimaryKey(curriculumScheduledb.getPurchaseCourseId());

			//总课时  剩余课时 add class
			if(curriculumScheduledb.getState() ==null ){
				updateSchedule(curriculumSchedule, curriculumScheduledb, purchaseCourseView);
			} else if (curriculumScheduledb.getState() != curriculumSchedule.getState()){
				//编辑恢复
				String log = mapper.getLog(curriculumScheduledb.getId());
				if(StringUtils.isNotBlank(log)){
					ScheduleLog scheduleLog = GsonUtils.toObject(log, ScheduleLog.class);
					if(scheduleLog.getHoursEnrolled() !=null){
						//总课时减少
						int i = purchaseCourseView.getHoursEnrolled() - scheduleLog.getHoursEnrolled();
						Map<String,Object> sqlMap = new HashMap<>();
						sqlMap.put("hoursEnrolled",i);
						sqlMap.put("uniqueid",curriculumScheduledb.getPurchaseCourseId());
						purchaseCourseViewMapper.updateEnro(sqlMap);
					}

					if(scheduleLog.getHoursRemaining() !=null){
						//剩余课时增加
						Integer hoursRemaining = purchaseCourseView.getHoursRemaining()+scheduleLog.getHoursRemaining();
						Map<String,Object> sqlMap = new HashMap<>();
						sqlMap.put("hoursRemaining",hoursRemaining);
						sqlMap.put("uniqueid",curriculumScheduledb.getPurchaseCourseId());
						purchaseCourseViewMapper.updateRemain(sqlMap);
					}

					if(scheduleLog.getAddClassId()!=null && scheduleLog.getAddClassId().size()>0){
						//删除add class
						for(Integer id:scheduleLog.getAddClassId()){
							mapper.deleteSchedule(id);
						}
					}
				}
				curriculumScheduledb = mapper.selectByPrimaryKey(curriculumSchedule);
				purchaseCourseView = purchaseCourseViewMapper.selectByPrimaryKey(curriculumScheduledb.getPurchaseCourseId());

				updateSchedule(curriculumSchedule,curriculumScheduledb,purchaseCourseView);
			} else {
				mapper.updateByPrimaryKeySelective(curriculumSchedule);
			}
		} catch (Exception e){
			e.printStackTrace();
		}
		return curriculumSchedule;
	}

	private void updateSchedule(CurriculumSchedule curriculumSchedule,CurriculumSchedule curriculumScheduledb,PurchaseCourseView purchaseCourseView) throws Exception{
		Integer statue=curriculumSchedule.getState();
		if(statue==0){
			mapper.updateByPrimaryKeySelective(curriculumSchedule);
		} else if(statue==3||statue==7){ // complete ; student absent ;减少剩余课时
			//总课时不变 剩余课时减少 课表不变
			mapper.updateByPrimaryKeySelective(curriculumSchedule);
			Integer classLength = curriculumScheduledb.getClassLength();
			Integer hoursRemaining = purchaseCourseView.getHoursRemaining()-classLength;
			Map<String,Object> sqlMap = new HashMap<>();
			sqlMap.put("hoursRemaining",hoursRemaining);
			sqlMap.put("uniqueid",curriculumScheduledb.getPurchaseCourseId());
			purchaseCourseViewMapper.updateRemain(sqlMap);

			ScheduleLog scheduleLog = ScheduleLog.builder().hoursRemaining(classLength).build();
			Map map = new HashMap();
			map.put("id",curriculumScheduledb.getId());
			map.put("log", GsonUtils.toJson(scheduleLog));
			purchaseCourseViewMapper.updateLog(map);

		}else if(statue==1 || statue==2 || statue==4){ //no class； student on level;teacher on level;
			//总课时不变  剩余课时不变 课表增加
			mapper.updateByPrimaryKeySelective(curriculumSchedule);
			List<Integer> ids = addLevalClass(curriculumScheduledb.getPurchaseCourseId(), curriculumScheduledb.getClassLength(), null);

			ScheduleLog scheduleLog = ScheduleLog.builder().addClassId(ids).build();
			Map map = new HashMap();
			map.put("id",curriculumScheduledb.getId());
			map.put("log", GsonUtils.toJson(scheduleLog));
			purchaseCourseViewMapper.updateLog(map);

		}else if(statue==5 || statue==6){//Teacher absent
			// 总课时不变 剩余课时增加 课表增加make up class
			mapper.updateByPrimaryKeySelective(curriculumSchedule);
			Integer classLength = curriculumScheduledb.getClassLength();
			Integer hoursRemaining = purchaseCourseView.getHoursRemaining()+classLength;
			Map<String,Object> sqlMap = new HashMap<>();
			sqlMap.put("hoursRemaining",hoursRemaining);
			sqlMap.put("uniqueid",curriculumScheduledb.getPurchaseCourseId());
            purchaseCourseViewMapper.updateRemain(sqlMap);

			List<Integer> ids = addLevalClass(curriculumScheduledb.getPurchaseCourseId(), curriculumScheduledb.getClassLength(), 6);

			ScheduleLog scheduleLog = ScheduleLog.builder().addClassId(ids).hoursRemaining( -curriculumScheduledb.getClassLength()).build();
//			ScheduleLog scheduleLog = ScheduleLog.builder().addClassId(ids).hoursEnrolled( -curriculumScheduledb.getClassLength()).build();
			Map map = new HashMap();
			map.put("id",curriculumScheduledb.getId());
			map.put("log", GsonUtils.toJson(scheduleLog));
			purchaseCourseViewMapper.updateLog(map);
		}
	}

	@Override
	public CurriculumSchedule update(final CurriculumSchedule curriculumSchedule) {
		mapper.updateByPrimaryKey(curriculumSchedule);
		return curriculumSchedule;
	}

	@Override
	public CurriculumSchedule delete(final Integer id) {

		return null;
	}

	@Override
	public Map<String, String> countLastMonth(final String studentId) {
		return mapper.countLastMonth(studentId);
	}

	@Override
	public List<CurriculumScheduleView> getViewByPurchaseCourse(final CurriculumSchedule curriculumSchedule) {
		final Page<CurriculumSchedule> page = PageHelper.startPage(curriculumSchedule.getPageNum(), 300);
		return mapper.getViewByPurchaseCourse(curriculumSchedule);
	}

	@Override
	public List<CurriculumScheduleView> getByTeacherIdAndDate(final CurriculumSchedule curriculumSchedule)
			throws ParseException {
		curriculumSchedule.setClassDate(DateUtil.str2Date(curriculumSchedule.getClassTime()));
		return mapper.getByTeacherIdAndDate(curriculumSchedule);
	}



	@Transactional
	@Override
	public CurriculumSchedule add(final CurriculumSchedule curriculumSchedule) {

		final Date classDate = curriculumSchedule.getClassDate();
		int week = cn.hutool.core.date.DateUtil.dayOfWeek(classDate) - 1;
		if (week == 0) {
			week = 1;
		}

		final PurchaseCourse pc = pcmapper.selectByPrimaryKey(curriculumSchedule.getPurchaseCourseId());
		curriculumSchedule.setClassWeek(DateUtil.dayInWeek(curriculumSchedule.getClassDate()));
		curriculumSchedule.setTeacherId(pc.getTeacherId());
		curriculumSchedule.setStudentId(pc.getStudentId());
		curriculumSchedule.setMaterial(pc.getMaterial());
		curriculumSchedule.setClassWeek(week);
		String s = cn.hutool.core.date.DateUtil.parse(curriculumSchedule.getClassTime())
													 .offset(DateField.MINUTE, curriculumSchedule.getClassLength())
													 .toTimeStr();
		curriculumSchedule.setClassTimeEnd(s.substring(0,s.lastIndexOf(":")));

		final CurriculumSchedule curriculumSchedule1 = new CurriculumSchedule();
		curriculumSchedule1.setPurchaseCourseId(curriculumSchedule.getPurchaseCourseId());
		final List<CurriculumScheduleView> viewByPurchaseCourse = mapper.getViewByPurchaseCourse(curriculumSchedule1);

		int count = 0;
		for (int i = viewByPurchaseCourse.size() - 1; i >= 0; i--) {
			final Integer id = viewByPurchaseCourse.get(i).getId();
			Integer classLength = viewByPurchaseCourse.get(i).getClassLength();

			if (count < curriculumSchedule.getClassLength()) {
				if (curriculumSchedule.getClassLength() - count >= classLength) {
					count = count + classLength;
					mapper.updateDeleteById((id.longValue()));
				}
			}
		}

		curriculumSchedule.setIsDelete(0);


		 String classTime = curriculumSchedule.getClassTime();
		 String classTimeEnd = curriculumSchedule.getClassTimeEnd();
		if (classTime.indexOf("0")==0){
			curriculumSchedule.setClassTime(classTime.substring(1,classTime.length()));
		}
		if (classTimeEnd.indexOf("0")==0){
			curriculumSchedule.setClassTimeEnd(classTimeEnd.substring(1,classTimeEnd.length()));
		}
		return insert(curriculumSchedule);

//		final PurchaseCourse pc = pcmapper.selectByPrimaryKey(curriculumSchedule.getPurchaseCourseId());
//
//		final Integer classLength = curriculumSchedule.getClassLength();
//		final Date classDate = curriculumSchedule.getClassDate();
//		final String classTime = curriculumSchedule.getClassTime();
//		int week = cn.hutool.core.date.DateUtil.dayOfWeek(classDate) - 1;
//		if (week == 0) {
//			week = 1;
//		}
//		String classEndTime = cn.hutool.core.date.DateUtil.parse(classTime).offset(DateField.MINUTE, classLength).toTimeStr();


	}

	@Override
	public String deleteByPurchaseCourseId(final String purchaseCourseId) {
		mapper.deleteByPurchaseCourseId(purchaseCourseId);
		return "课程还原成功";
	}

	@Override
	public List<Map<String, String>> countByStateAndPc(final String pcid) {
		return mapper.countByStateAndPc(pcid);
	}

	/**
	 * 
	 * @Description: 补课
	 * @param purchase_course_id
	 *            课程购买ID
	 * @param totalLength
	 *            补课时长
	 * @throws ParseException
	 * @throws CloneNotSupportedException
	 */
	@Override
	public List<Integer> addLevalClass(final String purchaseCourseId, int length,Integer statue)
			throws ParseException, CloneNotSupportedException {
		final List<CurriculumSchedule> curriculumSchedules = mapper.getByPurchaseCourseId(purchaseCourseId);
		final String lastDate = mapper.getLastClassDate(purchaseCourseId);
		Date startDate = DateUtil.str2Date(lastDate);
		startDate = DateUtil.addDay(startDate, 1);
		// 获取开始日期是周几
		final int day = DateUtil.dayInWeek(startDate);
		// 用于保存的集合
		final List<CurriculumSchedule> inserts = new ArrayList<>();
		final int s = curriculumSchedules.get(0).getClassWeek();
		final int e = curriculumSchedules.get(curriculumSchedules.size() - 1).getClassWeek();
		if (day > s && day <= e) {// 先处理零散的时间
			for (final CurriculumSchedule c : curriculumSchedules) {
				c.setId(null);
				if (length <= 0) {
					break;
				}
				final int d = c.getClassWeek();
				if (d >= day) {
					final Date date = DateUtil.addDay(startDate, d - day);
					c.setClassDate(date);
					final CurriculumSchedule nc = c.clone();
					if (length < nc.getClassLength()) {
						final String end = getEnd(c, length);
						nc.setClassLength(length);
						nc.setClassTimeEnd(end);
						length = 0;
					} else {
						length -= nc.getClassLength();
					}
					inserts.add(nc);
				} else {
					continue;
				}
			}
		}
		final int lastDay = curriculumSchedules.get(0).getClassWeek();
		Date date = DateUtil.getNextWeekDate(startDate, lastDay);
		while (length > 0) {
			date = DateUtil.getNextWeekDate(date, lastDay);
			int before = lastDay;
			for (final CurriculumSchedule c : curriculumSchedules) {
				if (length <= 0) {
					break;
				}
				final int d = c.getClassWeek();
				final int classLength = c.getClassLength();
				date = DateUtil.addDay(date, d - before);
				if (length < classLength) {
					c.setClassDate(date);
					c.setClassLength(length);
					final String end = getEnd(c, length);
					c.setClassTimeEnd(end);
					inserts.add(c.clone());
					length = 0;
				} else {
					date = DateUtil.addDay(date, d - before);
					c.setClassDate(date);
					inserts.add(c.clone());
					before = d;
					length -= classLength;
				}
			}
		}
		if(statue!=null){
			for(CurriculumSchedule curriculumSchedule:inserts){
				curriculumSchedule.setState(statue);
			}
		}
		List<Integer> ids = new ArrayList<>();
		for(CurriculumSchedule c:inserts){
			mapper.addOne(c);
			Integer id = mapper.getIdNew();
			ids.add(id);
		}
		return ids;
//		mapper.addAll(inserts);
	}

	/**
	 * @Description:获取结束时间
	 * @param c
	 * @param length
	 * @return String
	 */
	private static String getEnd(final CurriculumSchedule c, final int length) {
		String end = "";
		final String start = c.getClassTime();
		final String[] strings = start.split(":");
		int m = Integer.valueOf(strings[1]) + length;
		final int h = m / 60 + Integer.valueOf(strings[0]);
		m = m % 60;
		final String ho = h > 9 ? h + "" : "0" + h;
		final String mi = m > 9 ? m + "" : "0" + m;
		end = ho + ":" + mi;
		System.out.println(m);
		return end;
	}

	@Transactional
	@Override
	public Boolean addClass(String picd, Integer hoursClass)throws Exception{
		//总课时增加
		PurchaseCourseView purchaseCourseView = purchaseCourseViewMapper.selectByPrimaryKey(picd);
		Map<String,Object> sqlMap = new HashMap<>();
		sqlMap.put("hoursEnrolled",purchaseCourseView.getHoursEnrolled()+hoursClass);
		sqlMap.put("uniqueid",picd);
//		purchaseCourseViewMapper.updateEnro(sqlMap);

		//剩余课时增加
		Integer hoursRemaining = purchaseCourseView.getHoursRemaining()+hoursClass;
		sqlMap.put("hoursRemaining",hoursRemaining);
		sqlMap.put("uniqueid",picd);
		purchaseCourseViewMapper.updateRemain(sqlMap);

		//课表顺延
		addLevalClass(picd, hoursClass, null);
		return true;
	}
}
